package com.ruoyi.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.thread.ReqThreadLocalUtil;
import com.ruoyi.common.utils.RequestInfo;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.utils.sqResponseStatus;
import com.ruoyi.domain.Booking;
import com.ruoyi.domain.Customer;
import com.ruoyi.domain.dto.BookingDto;
import com.ruoyi.domain.vo.BookingVo;
import com.ruoyi.service.IBookingService;
import com.ruoyi.service.ICustomerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.ruoyi.common.constant.ServerConstants.*;

/**
 * <p>
 * 客户预约表 前端控制器
 * </p>
 *
 * @author 林颖
 * @since 2024-02-08
 */
@RestController
@RequestMapping("/bookings")
@Anonymous
public class BookingController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private IBookingService bookingService;

    @Autowired
    private ICustomerService customerService;

    @PostMapping("/saveBookingInfo")
    public AjaxResult saveBookingInfo(@RequestBody Booking booking) {

        if (booking == null) {
            return AjaxResult.error(sqResponseStatus.ERROR.getStatusCode(), "提交预约信息异常！");
        }

        try {
            String bookinId = RandomUtil.simpleUUID();
            booking.setBookingId(bookinId);

            // 将时间戳转换为指定格式日期字符串
            Long timestamp = Long.parseLong(booking.getAppointmentTime());
            Date date = new Date(timestamp);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String formattedDate = sdf.format(date);
            booking.setAppointmentTime(formattedDate);

            bookingService.save(booking);
            return AjaxResult.success("提交预约信息成功！");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("saveBookingInfo Method Exception======>{}", e.getMessage());
            return AjaxResult.error("提交预约信息异常！");
        }
    }

    @PostMapping("/updateBookingInfo")
    public AjaxResult updateBookingInfo(@RequestBody Booking booking) {

        if (booking == null) {
            return AjaxResult.error(sqResponseStatus.ERROR.getStatusCode(), "修改预约信息异常！");
        }

        try {
            // 将时间戳转换为指定格式日期字符串
            Long timestamp = Long.parseLong(booking.getAppointmentTime());
            Date date = new Date(timestamp);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String formattedDate = sdf.format(date);
            booking.setAppointmentTime(formattedDate);

            bookingService.updateById(booking);
            return AjaxResult.success("修改预约信息成功！");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("updateBookingInfo Method Exception======>{}", e.getMessage());
            return AjaxResult.error("修改预约信息异常！");
        }
    }

    @PostMapping("/deleteBookingInfo")
    public AjaxResult deleteBookingInfo(@RequestParam("bookingId") String bookingId) {

        if (StringUtils.isEmpty(bookingId)) {
            return AjaxResult.error(sqResponseStatus.ERROR.getStatusCode(), "撤销预约信息异常！");
        }

        try {
            bookingService.removeById(bookingId);
            return AjaxResult.success("撤销预约信息成功！");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("deleteBookingInfo Method Exception======>{}", e.getMessage());
            return AjaxResult.error("撤销预约信息异常！");
        }
    }

    @PostMapping("/getBookingInfo")
    public AjaxResult getBookingInfo(@RequestBody Booking bookingParam) {
        //最终返回的数据
        List<BookingDto> finBookingList = new ArrayList<>();

        try {
            //1.根据条件查询出对应的排单信息
            LambdaQueryWrapper<Booking> lqw = new LambdaQueryWrapper<>();
            lqw.eq(Booking::getCustomerId, bookingParam.getCustomerId());
            lqw.eq(bookingParam.getQueueStatus() != null && !bookingParam.getQueueStatus().isEmpty(), Booking::getQueueStatus, bookingParam.getQueueStatus());
            lqw.orderByAsc(Booking::getAppointmentTime);
            List<Booking> bookingList = bookingService.list(lqw);

            //2.遍历排单信息，查询当天的排单人数，然后查出其前方还有多少个人
            for (Booking booking : bookingList) {
                BookingDto bookingDto = new BookingDto();
                BeanUtil.copyProperties(booking, bookingDto);
                Integer aheadCount = bookingService.getAheadCount(booking);//获取前方人数
                Double currentRate = bookingService.getCurrentRate(booking);//获取排队进度
                bookingDto.setAheadCount(aheadCount);
                bookingDto.setCurrentRate(currentRate);

                finBookingList.add(bookingDto);
            }
            return AjaxResult.success("查询排单信息成功！", finBookingList);
        } catch (Exception e) {
            logger.error("getBookingInfo Method Exception======>{}", e.getMessage());
            return AjaxResult.error("查询排单信息异常！");
        }
    }


    @PostMapping("/getBookingList")
    public AjaxResult getBookingList(@RequestBody BookingVo bookingInfo) {
        //最终返回的数据
        List<BookingDto> finBookingList = new ArrayList<>();
        String isManager = "";

        // 获取当前访问端
        RequestInfo requestInfo = ReqThreadLocalUtil.getReq();
        String requestFlag = requestInfo.getRequestFlag();

        //查询当前查询者是否为管理员，若是管理员则展示所有的信息
        if (StringUtils.isNotEmpty(bookingInfo.getCustomerId())) {
            LambdaQueryWrapper<Customer> customerLambdaQueryWrapper = new LambdaQueryWrapper<>();
            customerLambdaQueryWrapper.eq(Customer::getCustomerId, bookingInfo.getCustomerId());
            Customer customer = customerService.getOne(customerLambdaQueryWrapper);
            isManager = customer.getIsManager();
        }

        try {
            //1.根据条件查询出对应的排单信息
            LambdaQueryWrapper<Booking> lqw = new LambdaQueryWrapper<>();
            if (CLIENT_REQ_FLAG.equals(requestFlag)){
                lqw.eq(bookingInfo.getCustomerId() != null &&
                                !bookingInfo.getCustomerId().isEmpty() &&
                                isManager.equals(NOT_MANAGER_USER),
                        Booking::getCustomerId, bookingInfo.getCustomerId());
            }
            lqw.like(bookingInfo.getName() != null && !bookingInfo.getName().isEmpty(), Booking::getName, bookingInfo.getName());
            lqw.eq(bookingInfo.getGender() != null && !bookingInfo.getGender().isEmpty(), Booking::getGender, bookingInfo.getGender());
            lqw.eq(bookingInfo.getPhoneNumber() != null && !bookingInfo.getPhoneNumber().isEmpty(), Booking::getPhoneNumber, bookingInfo.getPhoneNumber());
            lqw.eq(bookingInfo.getQueueStatus() != null && !bookingInfo.getQueueStatus().isEmpty(), Booking::getQueueStatus, bookingInfo.getQueueStatus());
            lqw.gt(bookingInfo.getStartTime() != null && !bookingInfo.getStartTime().isEmpty(), Booking::getAppointmentTime, bookingInfo.getStartTime());
            lqw.lt(bookingInfo.getEndTime() != null && !bookingInfo.getEndTime().isEmpty(), Booking::getAppointmentTime, bookingInfo.getEndTime());
            lqw.orderByAsc(Booking::getAppointmentTime);
            //1.初步查出分页数据
            IPage<Booking> page = new Page<>(bookingInfo.getPage(), bookingInfo.getPageSize());
            bookingService.page(page, lqw);
            List<Booking> bookingList = page.getRecords();


            //2.遍历排单信息，查询当天的排单人数，然后查出其前方还有多少个人
            for (Booking booking : bookingList) {
                BookingDto bookingDto = new BookingDto();
                BeanUtil.copyProperties(booking, bookingDto);
                Integer aheadCount = bookingService.getAheadCount(booking);//获取前方人数
                Double currentRate = bookingService.getCurrentRate(booking);//获取排队进度
                bookingDto.setAheadCount(aheadCount);
                bookingDto.setCurrentRate(currentRate);

                finBookingList.add(bookingDto);
            }

            //3.封装响应的分页数据
            IPage<BookingDto> resultData = new Page<>();
            BeanUtil.copyProperties(page, resultData);
            resultData.setRecords(finBookingList);
            return AjaxResult.success("查询排单信息成功！", resultData);
        } catch (Exception e) {
            logger.error("getBookingList Method Exception======>{}", e.getMessage());
            return AjaxResult.error(sqResponseStatus.ERROR.getStatusCode(), "查询排单信息异常！");
        }
    }

    @PostMapping("/changeQueueStatus")
    public AjaxResult changeQueueStatus(@RequestBody Booking booking) {
        try {
            LambdaQueryWrapper<Booking> lqw = new LambdaQueryWrapper<>();
            lqw.eq(Booking::getBookingId, booking.getBookingId());
            Booking bookingInfo = bookingService.getOne(lqw);
            bookingInfo.setQueueStatus(booking.getQueueStatus());

            bookingService.updateById(bookingInfo);
            return AjaxResult.success("更改排队状态成功！");
        } catch (Exception e) {
            logger.error("changeQueueStatus Method Exception======>{}", e.getMessage());
            return AjaxResult.error(sqResponseStatus.ERROR.getStatusCode(), "更改排队状态异常！");
        }
    }

    @PostMapping("/export")
    public void export(HttpServletResponse response, BookingVo bookingInfo)
    {
        // 获取当前访问端
        RequestInfo requestInfo = ReqThreadLocalUtil.getReq();
        String requestFlag = requestInfo.getRequestFlag();
        String isManager = "";

        //查询当前查询者是否为管理员，若是管理员则展示所有的信息
        if (StringUtils.isNotEmpty(bookingInfo.getCustomerId())) {
            LambdaQueryWrapper<Customer> customerLambdaQueryWrapper = new LambdaQueryWrapper<>();
            customerLambdaQueryWrapper.eq(Customer::getCustomerId, bookingInfo.getCustomerId());
            Customer customer = customerService.getOne(customerLambdaQueryWrapper);
            isManager = customer.getIsManager();
        }

        //根据条件查询出对应的排单信息
        LambdaQueryWrapper<Booking> lqw = new LambdaQueryWrapper<>();
        if (CLIENT_REQ_FLAG.equals(requestFlag)){
            lqw.eq(bookingInfo.getCustomerId() != null &&
                            !bookingInfo.getCustomerId().isEmpty() &&
                            isManager.equals(NOT_MANAGER_USER),
                    Booking::getCustomerId, bookingInfo.getCustomerId());
        }
        lqw.like(bookingInfo.getName() != null && !bookingInfo.getName().isEmpty(), Booking::getName, bookingInfo.getName());
        lqw.eq(bookingInfo.getGender() != null && !bookingInfo.getGender().isEmpty(), Booking::getGender, bookingInfo.getGender());
        lqw.eq(bookingInfo.getPhoneNumber() != null && !bookingInfo.getPhoneNumber().isEmpty(), Booking::getPhoneNumber, bookingInfo.getPhoneNumber());
        lqw.eq(bookingInfo.getQueueStatus() != null && !bookingInfo.getQueueStatus().isEmpty(), Booking::getQueueStatus, bookingInfo.getQueueStatus());
        lqw.gt(bookingInfo.getStartTime() != null && !bookingInfo.getStartTime().isEmpty(), Booking::getAppointmentTime, bookingInfo.getStartTime());
        lqw.lt(bookingInfo.getEndTime() != null && !bookingInfo.getEndTime().isEmpty(), Booking::getAppointmentTime, bookingInfo.getEndTime());
        lqw.orderByAsc(Booking::getAppointmentTime);
        List<Booking> bookingList = bookingService.list(lqw);

        //导出信息
        ExcelUtil<Booking> util = new ExcelUtil<Booking>(Booking.class);
        util.exportExcel(response, bookingList, "预约信息表");
    }
}

